package com.chandon.juc.thread_basic;

import com.chandon.juc.SleepThread;

import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 线程的状态与迁移
 *
 * @author Dong
 * @version 1.0
 * @date 2021-04-05 15:40
 */

public class T02_ThreadState {
    public static void main(String[] args) throws InterruptedException {

//        threadState_NEW_RUNNABLE_TERMINATED_Test();

//        threadState_WAITING_and_TIME_WAITING_Test();'

//        threadState_BLOCKED_Test();

        threadStateWithReentrantLock_WAITING_and_TIMED_WAITIN_Test();

    }

    private static void threadStateWithReentrantLock_WAITING_and_TIMED_WAITIN_Test() {
        ReentrantLock lock = new ReentrantLock();

        Thread t1 = new Thread(()->{
            lock.lock();
        });
        Thread t2 = new Thread(()->{
            lock.lock();
            SleepThread.sleep(5);
            lock.unlock();
        });

        t2.start();
        t1.start();
        SleepThread.sleep(1);
        System.out.println(t1.getState());
        System.out.println(t2.getState());
    }

    /**
     * 线程只有在进入synchronized代码块才有BLOCKED状态
     */
    private static void threadState_BLOCKED_Test() throws InterruptedException {
        final Object o = new Object();

        Thread t1 = new Thread(() -> {
            System.out.println("t1 start");
            synchronized (o) {
                System.out.println("t1拿到了锁");
            }
        });

        Thread t2 = new Thread(() -> {
            System.out.println("t2 start");
            synchronized (o){
                System.out.println("t2先拿到锁，持有5秒");
                SleepThread.sleep(5);
                System.out.println("t2 sleep结束");
            }
        });

        // 先启动t2拿到锁
        t2.start();
        // 主线程sleep
        SleepThread.sleep(1);
        // 启动t1线程抢锁
        t1.start();
        // 主线程sleep
        SleepThread.sleep(1);
        // BLOCKED
        System.out.println("1----t1:"+t1.getState());
        t1.join();
        System.out.println("1----t1:"+t1.getState());
    }

    /**
     * 使用LockSupport验证线程状态 WAITING,TIME_WAITING状
     */
    private static void threadState_WAITING_and_TIME_WAITING_Test() {
        Thread t = new Thread(() -> {
            System.out.println("park");
            LockSupport.park();
            SleepThread.sleep(5);
        });

        t.start();
        // 主线程sleep 1秒，确保子线程先执行了
        SleepThread.sleep(1);
        System.out.println("1----" + t.getState());
        LockSupport.unpark(t);
        SleepThread.sleep(1);
        System.out.println("2----" + t.getState());
    }


    /**
     * 线程状态NEW,RUNNABLE,TERMINATED状态验证
     *
     * @throws InterruptedException
     */
    private static void threadState_NEW_RUNNABLE_TERMINATED_Test() throws InterruptedException {
        Thread t = new Thread(() -> {
            System.out.println("2" + "----" + Thread.currentThread().getState());
            // 线程sleep
            SleepThread.sleep(5);
            System.out.println(Thread.currentThread().getName());

        });
        //  1.还未到start，只是new出来线程
        System.out.println("1" + "----" + t.getState());
        // 2.线程已启动开始执行，Runnable状态
        t.start();
        // 让t1子线程先执行结束
        t.join();
        System.out.println("3" + "----" + t.getState());
    }
}
